#!/usr/bin/env python
# # -*- coding: utf-8 -*-

"""
@File:      main_dj.py.py
@Author:    Jim.Dai.Cn
@Date:      2024/6/17 14:50
@Desc:         
"""
import json
import os
import shutil
import sys
import subprocess
import json5

from DataWizards.utils.global_functions import *
from DataWizards.config.config import *
from DataWizards.tools.DateCheckTool import *
from DataWizards.tools.ValueCheckTool import *
from DataWizards.tools.IntegrityCheckTool import *
from DataWizards.tools.CalculationCheckTool import *
from DataWizards.utils.doc2docx_osx import doc_to_docx_libre


def import_platform_specific_package():
    if sys.platform == "Windows":  # windows
        from DataWizards.utils.doc2docx_win import doc_to_docx_win
    else:  # macOS or linux
        from DataWizards.utils.doc2docx_osx import doc_to_docx_libre


# 调用函数以根据操作系统导入相应的包
# import_platform_specific_package()


def get_files(str_data_dir) -> list:
    current_dir = os.path.dirname(os.path.abspath(__file__))
    data_dir = os.path.join(current_dir, str_data_dir)
    if not os.path.isdir(data_dir):
        return []
    items_in_data = os.listdir(data_dir)
    files_only = [os.path.join(data_dir, item) for item in items_in_data if
                  (os.path.isfile(os.path.join(data_dir, item)) and not item.startswith('~$'))]
    print("checking files in directory => " + str_data_dir + ", total = " + str(len(files_only)))
    return files_only


def long_context_scanner(str_doc_path) -> list:
    print("")
    base_path = os.path.basename(str_doc_path)
    print("    init scanner for :" + base_path)
    arr_err = []  # sents
    doc_name, extension = os.path.splitext(os.path.basename(str_doc_path))
    # arr_err.extend(check_common(str_doc_path))      # 常识错误
    # arr_err.extend(check_unit(str_doc_path))        # 单位错误
    # arr_err.extend(check_logic(str_doc_path))       # 逻辑错误
    arr_err.extend(check_date(str_doc_path))  # 日期错误
    arr_err.extend(check_value(str_doc_path))  # 数值错误
    arr_err.extend(check_integrity(str_doc_path))  # 完整错误
    arr_err.extend(check_calc(str_doc_path))  # 计算错误
    # arr_err.extend(check_repetition(str_doc_path))    # 重复错误
    print(f"    raw result : {arr_err}")
    print(f"    unique result : {base_path}", end=" ")
    # arr_err_unique = arr_err
    unique_tuples = set(tuple(sorted(sublist)) for sublist in arr_err)
    arr_err_unique = [list(t) for t in unique_tuples]

    ret = {"id": doc_name, "sents": arr_err_unique}
    print(ret)
    return ret


def check_common(str_doc_path) -> list:
    print("common scanner for :" + str_doc_path)
    return [["第八条 因下列原因造成被保险人身故、伤残或医疗费用支出的，保险人不承担给付保险金责任：",
             "（六）被保险人遵医嘱服用、涂用、注射药物；"], ["若投保人未投保“必选责任”，可单独投保“可选责任”。"]]


def check_unit(str_doc_path) -> list:
    print("unit scanner for :" + str_doc_path)
    return [["第八条 因下列原因造成被保险人身故、伤残或医疗费用支出的，保险人不承担给付保险金责任：",
             "（六）被保险人遵医嘱服用、涂用、注射药物；"], ["若投保人未投保“必选责任”，可单独投保“可选责任”。"]]


def check_logic(str_doc_path) -> list:
    print("logic scanner for :" + str_doc_path)
    return [["第八条 因下列原因造成被保险人身故、伤残或医疗费用支出的，保险人不承担给付保险金责任：",
             "（六）被保险人遵医嘱服用、涂用、注射药物；"], ["若投保人未投保“必选责任”，可单独投保“可选责任”。"]]


def check_date(str_doc_path) -> list:
    print("      #4. date scanner for :" + str_doc_path)
    tool_date_check = DateCheckTool(str_doc_path)
    list_date_err = tool_date_check.call({'path_doc': str_doc_path})
    return list_date_err


def check_value(str_doc_path) -> list:
    print("      #5. value scanner for :" + str_doc_path)
    tool_value_check = ValueCheckTool(str_doc_path)
    list_date_err = tool_value_check.call({'path_doc': str_doc_path})
    return list_date_err


def check_integrity(str_doc_path) -> list:
    print("      #6. integrity scanner for :" + str_doc_path)
    tool_integrity_check = IntegrityCheckTool(str_doc_path)
    list_date_err = tool_integrity_check.call({'path_doc': str_doc_path})
    return list_date_err


def check_calc(str_doc_path) -> list:
    print("      #7. calculation scanner for :" + str_doc_path)
    tool_calc_check = CalculationCheckTool(str_doc_path)
    list_date_err = tool_calc_check.call({'path_doc': str_doc_path})
    return list_date_err


def check_repetition(str_doc_path) -> list:
    print("common scanner for :" + str_doc_path)
    return [["第八条 因下列原因造成被保险人身故、伤残或医疗费用支出的，保险人不承担给付保险金责任：",
             "（六）被保险人遵医嘱服用、涂用、注射药物；"], ["若投保人未投保“必选责任”，可单独投保“可选责任”。"]]


def save_result_to_file(list_result):
    print("=================")
    print(list_result)
    # 在 $dir_results 目录下创建 YYYYMMHHMMSS 子文件夹，并保存内容到 $str_result_name 文件
    dir_name = str_get_current_date_time()
    new_dir_path = os.path.join(dir_results, dir_name)
    os.makedirs(new_dir_path, exist_ok=True)
    str_path = os.path.join(new_dir_path, str_result_name)
    print("save to file=>" + str_path)
    with open(str_path, "w", encoding="utf-8") as out_file:
        for list_item in list_result:
            out_file.write(json.dumps(list_item, ensure_ascii=False) + "\n")
    open_directory(new_dir_path)


def open_directory(directory_path):
    if sys.platform == "win32":  # Windows系统
        os.startfile(directory_path)  # 使用os.startfile打开目录
    elif sys.platform == "darwin":  # Mac系统
        subprocess.call(["open", directory_path])  # 使用subprocess调用open命令
    else:  # 假设为Linux或其他Unix-like系统
        subprocess.call(["xdg-open", directory_path])  # 使用xdg-open命令


def prepare_docs(directory_path, out_path):
    """
    对给定的test_data 文件进行预处理， doc 文件 转为 docx, docx pdf 等照抄，存入 out_path
    :param directory_path: 初始doc目录, 例如 round1_test_data/
    :param out_path: 输出doc目录，例如 workspace/round1_test_data/
    :return:
    """
    # clean up workspace
    print("Clean up workspace => " + out_path)
    if os.path.exists(out_path):
        shutil.rmtree(os.path.abspath(out_path))
    os.makedirs(os.path.abspath(out_path), exist_ok=True)
    list_file = get_files(directory_path)
    int_total = len(list_file)
    int_counter = 1
    print(f"Preparing workspace => {out_path}, total = {int_total}")
    int_convert_count = 0
    for file in list_file:
        print(f"  [{int_counter}/{int_total}] = {os.path.basename(file)}", end='')
        int_counter += 1
        int_result = prepare_one_file(file, out_path)  # 如果转换了返回1 如果复制返回0
        int_convert_count += int_result
    print(f"Prepare docs done. Total = {int_total}, converted doc count = {int_convert_count}.")


def prepare_one_file(in_file, str_out_directory):
    # 获取输入文件的扩展名
    f_name, ext_name = os.path.splitext(os.path.basename(in_file))
    absolute_path = os.path.abspath(str_out_directory)
    if not absolute_path.endswith(os.sep):
        absolute_path += os.sep
    os.makedirs(absolute_path, exist_ok=True)
    out_file = os.path.abspath(absolute_path + f_name + '.docx')
    if ext_name.lower() == '.doc':  # 检查文件是否为.doc文件
        # print("doc file, converting to docx.")
        doc_to_docx_libre(in_file, out_file)
        return 1
    else:
        shutil.copy(in_file, out_file)
        print(f"  == Copied to => {out_file}")
        return 0


if __name__ == "__main__":
    # step 1 : copy test_data to workspace, convert doc to docx
    flag_skip_convert = 0
    if flag_skip_convert == 0:
        print("====STEP 1: prepare docs ====")
        prepare_docs(dir_test_doc, dir_workspace)

    # step 2 : check files
    print("====STEP 2====")
    list_docx_files = get_files(dir_workspace)
    list_err_all = []
    scan_counter = 1
    scan_total = len(list_docx_files)
    for str_file_path in list_docx_files:
        # debug purpose
        # debug_file = '风城油田夏子街转油站完善工程'
        root_name, ext = os.path.splitext(os.path.basename(str_file_path))
        print(f"  [{scan_counter}/{scan_total}] = {root_name}", end='')
        # if debug_file == root_name: # debug
        if scan_counter < 5:  # debug
            scan_result = long_context_scanner(str_file_path)
            list_err = list_err_all.append(scan_result)
            print(list_err)
            print(' => done.')
        scan_counter += 1

    # step3 :  save results
    print("====STEP 3====")
    save_result_to_file(list_err_all)
    print("Done saving file.")
